#ifndef SEARCHNODE_H
#define SEARCHNODE_H

#include "puzzlestate.h"
#include <memory>
#include <vector>

class SearchNode : public std::enable_shared_from_this<SearchNode>
{
public:
    SearchNode(const PuzzleState& state, int g = 0, int h = 0, 
               std::shared_ptr<SearchNode> parent = nullptr, int action = -1);
    
    // 添加一个只接受状态和父节点的构造函数
    SearchNode(const PuzzleState& state, std::shared_ptr<SearchNode> parent);
    
    // 添加一个接受状态、父节点、动作和g值的构造函数
    SearchNode(const PuzzleState& state, std::shared_ptr<SearchNode> parent, int action, int g);
    
    // 获取当前状态
    PuzzleState getState() const { return state; }
    
    // 获取和设置g值（从起点到当前节点的实际代价）
    int getG() const { return g; }
    void setG(int value) { g = value; }
    
    // 获取和设置h值（从当前节点到目标的估计代价）
    int getH() const { return h; }
    void setH(int value) { h = value; }
    
    // 获取f值（g + h，A*算法中的总估计代价）
    int getF() const { return g + h; }
    
    // 设置f值（A*算法中需要）
    void setF(int value) { /* f = g + h，所以不需要单独存储f值 */ }
    
    // 获取父节点
    std::shared_ptr<SearchNode> getParent() const { return parent; }
    void setParent(std::shared_ptr<SearchNode> p) { parent = p; }
    
    // 获取导致此节点的动作（0:上, 1:下, 2:左, 3:右）
    int getAction() const { return action; }
    void setAction(int a) { action = a; }
    
    // 获取深度（从根节点到此节点的步数）
    int getDepth() const;
    
    // 获取从根节点到此节点的路径
    std::vector<PuzzleState> getPath() const;
    
    // 获取从根节点到此节点的动作序列
    std::vector<int> getActionPath() const;
    
    // 检查是否是根节点
    bool isRoot() const { return parent == nullptr; }
    
    // 重载比较运算符，用于优先队列
    bool operator<(const SearchNode& other) const;
    bool operator>(const SearchNode& other) const;
    bool operator==(const SearchNode& other) const;
    
private:
    PuzzleState state;  // 当前状态
    int g;              // 从起点到当前节点的实际代价
    int h;              // 从当前节点到目标的估计代价（启发式值）
    std::shared_ptr<SearchNode> parent;  // 父节点
    int action;         // 导致此节点的动作
};

#endif // SEARCHNODE_H